package org.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.example.domain.ResponseResult;
import org.example.domain.dto.ArticleListDto;
import org.example.domain.entity.*;
import org.example.domain.vo.*;
import org.example.mapper.ArticleMapper;
import org.example.mapper.CategoryMapper;
import org.example.mapper.UserMapper;
import org.example.service.ArticleService;
import org.example.utils.BeanCopyUtils;
import org.example.utils.RedisCache;
import org.example.utils.SecurityUtils;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Objects;

@Service
@RequiredArgsConstructor
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper,Article> implements ArticleService {

    private final ArticleMapper articleMapper;

    private final RedisCache redisCache;

    private final CategoryMapper categoryMapper;

    private final UserMapper userMapper;


    @Override
    public ResponseResult hotArticleList() {

        List<Article> articleList = articleMapper.getHotArticle();

        for(int i=0;i<articleList.size();i++){
            Integer id = articleList.get(i).getId();
            Integer articleViewCount = redisCache.getCacheMapValue("ArticleViewCount", id.toString());
            articleList.get(i).setViewCount(articleViewCount);
        }

        List<HotArticleVo> hotArticleVoList = BeanCopyUtils.copyBeanList(articleList, HotArticleVo.class);
        return ResponseResult.okResult(hotArticleVoList);
    }

    @Override
    public ResponseResult updateViewCount(Integer id) {

        redisCache.incrementCacheMapValue("ArticleViewCount",id.toString(),1);
        return ResponseResult.okResult();

    }


    @Override
    public ResponseResult articleList(ArticleListDto articleListDto) {

        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        if(articleListDto.getCategoryId() != null && articleListDto.getCategoryId()>0){
            queryWrapper.eq(Article::getCategoryId,articleListDto.getCategoryId());
        }
        queryWrapper.eq(Article::getStatus,0);
        Page<Article> page = new Page<>();
        page.setCurrent(articleListDto.getPageNum());
        page.setSize(articleListDto.getPageSize());
        page(page,queryWrapper);

        List<Article> articleLists = page.getRecords();

        for(Article article : articleLists){
            User user = userMapper.SelectByUserId(article.getUserId());
            Integer articleViewCount = redisCache.getCacheMapValue("ArticleViewCount", article.getId().toString());
            if(!Objects.isNull(user)){
                article.setUsername(user.getNickName());
            }
            article.setViewCount(articleViewCount);
        }
        List<ArticleListVo> articleListVos = BeanCopyUtils.copyBeanList(articleLists, ArticleListVo.class);
        PageVo pageVo = new PageVo(articleListVos,page.getTotal());
        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult getArticleDetail(Integer id) {

        Article article = articleMapper.getArticleById(id);

        Category category = categoryMapper.getCategoryById(article.getCategoryId());

        User user = userMapper.SelectByUserId(article.getUserId());
        if(!Objects.isNull(category)) {
            article.setCategoryName(category.getName());
        }
        if(!Objects.isNull(user)){
            article.setUsername(user.getNickName());
            article.setAvatar(user.getAvatar());
        }
        Integer articleViewCount = redisCache.getCacheMapValue("ArticleViewCount", article.getId().toString());
        article.setViewCount(articleViewCount);
        ArticleDetailVo articleDetailVo = BeanCopyUtils.copyBean(article,ArticleDetailVo.class);

        return ResponseResult.okResult(articleDetailVo);
    }

    @Override
    public ResponseResult addArticle(Article article) {
        Integer userId = SecurityUtils.getUserId();
        article.setUserId(userId);
        return ResponseResult.okResult(save(article));
    }

    @Override
    public ResponseResult getArticleList(ArticleListDto articleListDto) {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(articleListDto.getTitle()), Article::getTitle,articleListDto.getTitle());
        if(articleListDto.getStatus() != null){
            queryWrapper.eq(Article::getStatus,articleListDto.getStatus());
        }
        Page<Article> page = new Page<>();
        page.setCurrent(articleListDto.getPageNum());
        page.setSize(articleListDto.getPageSize());
        page(page,queryWrapper);

        PageVo pageVo = new PageVo(page.getRecords(),page.getTotal());
        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult updateArticle(Article article) {
        Integer userId = SecurityUtils.getUserId();
        article.setUserId(userId);
        return ResponseResult.okResult(updateById(article));
    }

    @Override
    public ResponseResult recommendArticles() {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Article::getStatus,0);
        queryWrapper.orderByAsc(Article::getViewCount);
        Page<Article> page = new Page<>(1,6);
        page(page,queryWrapper);
        List<Article> articles = page.getRecords();

        for(Article article : articles){
            if(article.getUserId() == null){
                continue;
            }
            User user = userMapper.SelectByUserId(article.getUserId());
            if(user == null){
                continue;
            }
            article.setUsername(user.getUserName());
        }
        List<RecommendArticlesVo> recommendArticlesVos = BeanCopyUtils.copyBeanList(articles, RecommendArticlesVo.class);
        return ResponseResult.okResult(recommendArticlesVos);
    }

    @Override
    public ResponseResult userArticles(ArticleListDto articleListDto) {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Article::getStatus,0);
        Integer id = SecurityUtils.getUserId();
        queryWrapper.eq(Article::getUserId,id);
        Page<Article> page = new Page<>();
        page.setSize(articleListDto.getPageSize());
        page.setCurrent(articleListDto.getPageNum());
        page(page,queryWrapper);
        List<Article> articles = page.getRecords();

        for(Article article : articles){
            if(article.getUserId() == null){
                continue;
            }
            User user = userMapper.SelectByUserId(article.getUserId());
            if(user == null){
                continue;
            }
            article.setUsername(user.getUserName());
        }
        PageVo pageVo = new PageVo(articles,page.getTotal());
        return ResponseResult.okResult(pageVo);

    }


}
